<?php

/**
 * YiibackendModule 
 * 
 * @uses CWebModule
 * @package yiibackend
 * @version $id$
 * @copyright 2011 
 * @author Revin Roman <xgismox@gmail.com> 
 * @license BSD
 */
class YiibackendModule extends CWebModule{
    
    private $_assetsUrl;
    protected $model;
    public $attributesWidgets=null;
    public $_modelsList=array();
    public $_moduleBlocks=array();
    public static $fileExt='.php';
    private $controller;
    public $password;   
    public $registerBlocks=array();
    public $registerModels=array();
    public $excludeModels=array();
    public $timeformat = 'd.MM.y k:m';
    
    public function init(){
        
        Yii::app()->clientScript->registerCoreScript('jquery');
        
        Yii::app()->setComponents(array(
            'errorHandler'=>array(
                'errorAction'=>'yiibackend/default/error',
            ),
            'user'=>array(
                'class'=>'CWebUser',
                'stateKeyPrefix'=>'yiibackend',
                'loginUrl'=>Yii::app()->createUrl('yiibackend/default/login'),
            ),
        ));
        
        $this->setImport(array(
            'yiibackend.models.*',
            'yiibackend.components.*',
            'zii.widgets.grid.CGridColumn',
        ));
    }
    
    /**
     * Получение списка моделей
     * 
     * @access public
     * @return void
     */
    public function getModuleBlocks(){
        $blocks = $this->registerBlocks;
        if(!empty($blocks)){
            foreach($blocks as $block){
                $this->addBlock(Yii::getPathOfAlias($block).self::$fileExt);
            }
        }
        return array_unique($this->getBlocks());
    }
    
    /**
     * Добавление модели в список.
     * 
     * @param mixed $name 
     * @access protected
     * @return void
     */
    protected function addBlock($name){ array_push($this->_moduleBlocks, $name); }
    
    /**
     * Получение списка моделей.
     * 
     * @access protected
     * @return array
     */
    protected function getBlocks(){ return $this->_moduleBlocks; }
    
    /**
     * Получение списка моделей
     * 
     * @access public
     * @return void
     */
    public function getModelsList(){
        $models=$this->registerModels;
        if (!empty($models)){
            foreach($models as $model){
                // Импорт всех моделей(модели)
                Yii::import($model);
                
                if (substr($model, -1)=='*'){
                    // Если импортируем директорию с моделями,
                    // Получим список моделей
                    $files=CFileHelper::findFiles(Yii::getPathOfAlias($model));
                    if ($files){
                        foreach($files as $file){
                           $class_name=str_replace(self::$fileExt,'',substr(strrchr($file,DIRECTORY_SEPARATOR), 1));
                           $this->addModel($class_name);
                        }
                    }
                }else{
                    $class_name=substr(strrchr($model, "."), 1);
                    $this->addModel($class_name); 
                }
            }
        }
        return array_unique($this->getModels());
    }
    
    /**
     * Добавление модели в список.
     * 
     * @param mixed $name 
     * @access protected
     * @return void
     */
    protected function addModel($name){
        if (!in_array($name,$this->excludeModels))
            array_push($this->_modelsList, $name);
    }
    
    /**
     * Получение списка моделей.
     * 
     * @access protected
     * @return array
     */
    protected function getModels(){ return $this->_modelsList; }
    
    /**
     * Загрузка модели
     * 
     * @param string $name 
     * @access public
     * @return object
     */
    public function loadModel($name){
        $model=(string)$_GET['model_name'];
        $this->model=new $model;
        return $this->model;
    }
    
    public function createWidget($form,$model,$attribute)
    {
        $dbType=$model->tableSchema->columns[$attribute]->dbType;
        
        $widget=$this->getAttributeWidget($attribute);
        
        switch ($widget)
        {
            case 'textArea':
                return $form->textArea($model,$attribute,array('class'=>'vTextField'));
            break;
            
            case 'textField':
                return $form->textField($model,$attribute,array('class'=>'vTextField'));
            break;
            
            case 'password':
                $widgetData = $this->getAttributeData($attribute);
                $crypturl = Yii::app()->getController()->createUrl($widgetData['crypt']);
                return $form->textField($model,$attribute,array(
                    'class'=>'vTextField',
                    'onblur'=>'cryptpassword(this, \''.$crypturl.'\', \''.$model->$attribute.'\');'
                ));
            break;
            
            case 'dropDownList':
                return $form->dropDownList($model,$attribute,$this->getAttributeChoices($attribute),array('empty'=>'- select -'));
            break;

            case 'calendar': 
                $widgetData=array_slice($this->getAttributeData($attribute),2);
                
                $data=array(
                    'name'=>get_class($model).'['.$attribute.']',
                    'value'=>$model->$attribute,
                    'language'=>'ru',
                    'options'=>array(
                        'showAnim'=>'fold',
                        'dateFormat'=>'yy-mm-dd',
                    ),
                );
                
                if ($widgetData)
                    $data=array_merge($data,$widgetData);

                $this->controller->widget('zii.widgets.jui.CJuiDatePicker', $data);
            break;

            case 'boolean':
                return $form->checkBox($model,$attribute); 
            break;
            
            case 'file-path':
                $html = $form->fileField($model,$attribute);
                if(!empty($model->$attribute)){
                    $html .= '<br />'.$model->$attribute;
                }
                return $html;
            break;
            
            case 'timestamp-show':
                $widgetData = $this->getAttributeData($attribute);
                if(!isset($widgetData[2]) or empty($widgetData[2])) $widgetData[2] = $this->timeformat;
                $D = new CDateFormatter('ru');
                if($this->model->isNewRecord && $model->$attribute==0) $model->$attribute = time(); 
                return $D->format($widgetData[2], $model->$attribute); 
            break;

            default: 
                return $form->textField($model,$attribute,array('class'=>'vTextField')); 
            break;
        }
    }

    protected function getAttributeWidget($name)
    {
        if ($this->attributesWidgets!==null)
        {
            if (isset($this->attributesWidgets->$name))
                return $this->attributesWidgets->$name;
            else
            {
                $dbType=$this->model->tableSchema->columns[$name]->dbType; 
                if ($dbType=='text')
                    return 'textArea';
                else
                    return 'textField';
            }
        }

        if (method_exists($this->model,'attributeWidgets'))
            $attributeWidgets=$this->model->attributeWidgets();
        else
            return null;

        $temp=array();

        if (!empty($attributeWidgets))
        {
            foreach($attributeWidgets as $key=>$val)
            {
                if (isset($val[0]) && isset($val[1]))
                {
                    $temp[$val[0]]=$val[1];
                    $temp[$val[0].'Data']=$val;
                }
            }
        }

        $this->attributesWidgets=(object)$temp;

        return $this->getAttributeWidget($name);
    }

    protected function getAttributeData($attribute)
    {
        $attribute.='Data';
        if (isset($this->attributesWidgets->$attribute))
            return $this->attributesWidgets->$attribute;
        else
            return null;
    }

    /**
     * Получение массива значений атрибута.
     * Имя переменной массива с значениями должно быть: attributeNameChoices. 
     * Например categoryChoices.
     * 
     * @param mixed $attribute 
     * @access private
     * @return array
     */
    private function getAttributeChoices($attribute)
    {
        $data=array();
        $choicesName=(string)$attribute.'Choices';
        if (isset($this->model->$choicesName) && is_array($this->model->$choicesName))
            $data=$this->model->$choicesName;
        
        return $data;
    }

    public function getModelNamePlural($model)
    {
        if (is_string($model))
            $model=new $model;

        if (isset($model->adminName))
            return $model->adminName;
        else
            return get_class($model);
    }

    public function getObjectPluralName($model, $pos=0)
    {
        if (is_string($model))
            $model=new $model; 

        if (!isset($model->pluralNames))
            return get_class($model);
        else
            return $model->pluralNames[$pos];
    }

    /**
     * @return string the base URL that contains all published asset files.
     */
    public function getAssetsUrl()
    {
        if($this->_assetsUrl===null)
            $this->setAssetsUrl(Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('application.modules.yiibackend.assets')));
        return $this->_assetsUrl;
    }

    /**
     * @param string the base URL that contains all published asset files.
     */
    public function setAssetsUrl($value)
    {
        $this->_assetsUrl=$value;
    }
    
    public static function LS($action, $params=array()){
        return Yii::app()->createUrl('yiibackend/'.$action,$params);
    }
    /*public static function createActionUrl($action,$pk){
        $a=new CController;
        return $a->createUrl('manageModel',$data->primaryKey);
    }*/

    public static function t($message)
    {
        return Yii::t('YiibackendModule.yiibackend',$message);
    }

    public function beforeControllerAction($controller, $action)
    {
        if(parent::beforeControllerAction($controller, $action))
        {
            $this->controller=$controller;
            $route=$controller->id.'/'.$action->id;

            $publicPages=array(
                'default/login',
                'default/error',
            );
            if($this->password!==false && Yii::app()->user->isGuest && !in_array($route,$publicPages))
                Yii::app()->user->loginRequired();
            else
                return true;
        }
        return false;
    }
}
